package cn.sw.common.database.architecture.service.impl;

import cn.sw.common.database.architecture.dto.query.BaseQuery;
import cn.sw.common.database.architecture.service.BaseService;
import cn.sw.common.http.HttpResponse;
import cn.sw.common.utils.Mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 通用Service实现类
 *
 * @param <M> Mapper接口
 * @param <T> 实体类
 * @param <F> 表单类
 * @param <Q> 条件类
 * @author 张众森 (个人博客:https://)
 * @date 2025-05-10
 */
@Slf4j
public class BaseServiceImpl<M extends BaseMapper<T>, T, F, Q extends BaseQuery, V> extends ServiceImpl<M, T> implements BaseService<T, F, Q, V> {


    @Override
    public HttpResponse<?> RById(String id) {
        Assert.notNull(id, "ID不能为null");
        try {
            T entity = super.getById(id);
            return HttpResponse.ok(entity);
        } catch (Exception e) {
            return HttpResponse.error("查询失败：" + e);
        }
    }

    @Override
    public HttpResponse<?> RByIds(List<String> idList) {
        Assert.notNull(idList, "ID集合不能为null");
        try {
            List<T> entities = super.listByIds(idList);
            return HttpResponse.ok(entities);
        } catch (Exception e) {
            return HttpResponse.error("查询失败：" + e);
        }
    }

    @Override
    public HttpResponse<?> R(Q query) {
        Assert.notNull(query, "查询条件不能为null");
        try {
            T entity = Mapper.map(query, getEntityClass());
            QueryWrapper<T> queryWrapper = new QueryWrapper<>(entity);
            List<T> entities = super.list(queryWrapper);
            return HttpResponse.ok(entities);
        } catch (Exception e) {
//            return HttpResponse.ok(null);
            return HttpResponse.ok(e);
        }
    }

    @Override
    public List<T>  RTree(Q query) {
        Assert.notNull(query, "查询条件不能为null");
        try {
            T entity = Mapper.map(query, getEntityClass());
            QueryWrapper<T> queryWrapper = new QueryWrapper<>(entity);
            List<T> entities = super.list(queryWrapper);
            return entities;
        } catch (Exception e) {
            return  null;
        }
    }





    @Override
    public HttpResponse<?> P(Q query) {
        try {
            // 使用 Q 中的方法
            Page<T> page = Page.of(query.getPageNo(), query.getPageSize());
            // 使用反射检查是否有 getSort() 方法
            String sortValue = null;
            try {
                Method getSortMethod = query.getClass().getMethod("getSort");
                Object result = getSortMethod.invoke(query);
                if (result instanceof String) {
                    sortValue = (String) result;
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
            }

            // 如果存在 sort 参数，则添加排序
            if (sortValue != null && !sortValue.trim().isEmpty()) {
                page.setOrders(Collections.singletonList(OrderItem.asc("sort")));
            }

            QueryWrapper<T> queryWrapper = buildQueryWrapper(query);
            Page<T> resultPage = super.page(page, queryWrapper);
            return HttpResponse.ok(resultPage);
        } catch (Exception e) {
            return HttpResponse.error("分页查询失败：" + e.getMessage());
        }
    }


    protected QueryWrapper<T> buildQueryWrapper(Q query) {
        try {
            return new QueryWrapper<>(Mapper.map(query, getEntityClass()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }



    @Override
    @Transactional
    public HttpResponse<?> C(F form) {
        Assert.notNull(form, "表单不能为null");
        try {
            T map = Mapper.map(form, getEntityClass());
            boolean save = super.save(map);
            return HttpResponse.ok(save);
        } catch (Exception e) {
            return HttpResponse.error("创建失败:" + e);
        }

    }

    @Override
    public HttpResponse<?> CBatch(List<F> formList) {
        Assert.notNull(formList, "表单集合不能为null");
        try {
            Collection<T> entityList = formList.stream().map(form -> {
                try {
                    T entity = Mapper.map(form, getEntityClass());
                    return entity;
                } catch (Exception e) {
                    throw new RuntimeException("映射失败:" + e);
                }
            }).collect(Collectors.toList());
            boolean saved = super.saveBatch(entityList);
            return HttpResponse.ok(saved);
        } catch (Exception e) {
            return HttpResponse.error("批量创建失败:" + e);
        }
    }

    @Override
    public HttpResponse<?> UById(F form) {
        Assert.notNull(form, "表单不能为null");
        try {
            T entity = Mapper.map(form, getEntityClass());
            boolean updated = super.updateById(entity);
            return HttpResponse.ok("更新:" + updated);
        } catch (Exception e) {
            return HttpResponse.error("更新失败:" + e);
        }
    }

    @Override
    public HttpResponse<?> UBatchById(List<F> formList) {
        Assert.notNull(formList, "表单集合不能为null");
        try {
            Collection<T> entityList = formList.stream().map(form -> {
                try {
                    T entity = Mapper.map(form, getEntityClass());
                    return entity;
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }).collect(Collectors.toList());
            boolean updated = super.updateBatchById(entityList);
            return HttpResponse.ok("批量更新:" + updated);
        } catch (Exception e) {
            return HttpResponse.error("批量更新失败:" + e);
        }
    }

    @Override
    public HttpResponse<?> COrU(F form) {
        Assert.notNull(form, "表单不能为空");
        try {
            T entity = Mapper.map(form, getEntityClass());

            boolean result = super.saveOrUpdate(entity);
            String message = result ? "新增/更新成功" : "新增/更新未执行";
            return HttpResponse.ok(message);
        } catch (Exception e) {
            log.error("新增/更新操作失败", e);
            return HttpResponse.error("新增/更新失败，请稍后重试");
        }
    }

    @Override
    public HttpResponse<?> COrUBatch(List<F> formList) {
        Assert.notNull(formList, "表单集合不能为null");
        try {
            Collection<T> entityList = formList.stream().map(form -> {
                try {
                    T entity = Mapper.map(form, getEntityClass());
                    return entity;
                } catch (Exception e) {
                    throw new RuntimeException("映射表单失败: " + e.getMessage(), e);
                }
            }).collect(Collectors.toList());
            boolean success = super.saveOrUpdateBatch(entityList);
            return HttpResponse.ok(success ? "批量新增成功" : "批量更新成功");
        } catch (Exception e) {
            log.error("批量新增/更新失败: ", e);
            return HttpResponse.error("批量新增/更新失败，请稍后再试");
        }
    }

    @Override
    public HttpResponse<?> DById(String id) {
        Assert.notNull(id, "ID不能为null");
        try {
            boolean removed = super.removeById(id);
            return HttpResponse.ok("删除:" + removed);
        } catch (Exception e) {
            return HttpResponse.error("删除失败:" + e);
        }
    }

    @Override
    public HttpResponse<?> DByIds(List<String> idList) {
        Assert.notNull(idList, "ID集合不能为null");
        try {
            boolean removed = super.removeByIds(idList);
            return HttpResponse.ok("批量删除:" + removed);
        } catch (Exception e) {
            return HttpResponse.error("批量删除失败:" + e);
        }

    }
}
